package com.ruoyi.business.service.impl;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;

import com.ruoyi.business.BO.MatchInsertAssetInfoBO;
import com.ruoyi.business.BO.SelectAcAssetLeaseInfoBO;
import com.ruoyi.business.BO.SelectExpireAssetInfoBO;
import com.ruoyi.business.VO.AcAssetInfoVO;
import com.ruoyi.business.VO.AcAssetLeaseInfoVO;
import com.ruoyi.business.tool.AssetInfoTool;
import com.ruoyi.business.tool.UserInfoTool;
import com.ruoyi.system.domain.AcWorkOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.AcAssetInfoMapper;
import com.ruoyi.business.domain.AcAssetInfo;
import com.ruoyi.business.service.IAcAssetInfoService;

/**
 * 资产台账管理Service业务层处理
 *
 * @author ruoyi
 * @date 2025-01-15
 */
@Service
public class AcAssetInfoServiceImpl implements IAcAssetInfoService
{
    @Autowired
    private AcAssetInfoMapper acAssetInfoMapper;

    @Autowired
    private AssetInfoTool assetInfoTool;

    @Autowired
    private UserInfoTool userInfoTool;

    /**
     * 查询资产台账管理
     *
     * @param assetId 资产台账管理主键
     * @return 资产台账管理
     */
    @Override
    public AcAssetInfo selectAcAssetInfoByAssetId(Long assetId)
    {
        return acAssetInfoMapper.selectAcAssetInfoByAssetId(assetId);
    }

    /**
     * 查询资产台账管理列表
     *
     * @param acAssetInfo 资产台账管理
     * @return 资产台账管理
     */
    @Override
    public List<AcAssetInfo> selectAcAssetInfoList(AcAssetInfo acAssetInfo)
    {
        acAssetInfo.setDeptId(userInfoTool.getUserDeptId());
        return acAssetInfoMapper.selectAcAssetInfoList(acAssetInfo);
    }

    @Override
    public List<AcAssetInfo> selectAcAssetInfoIoc(AcAssetInfo acAssetInfo)
    {
        acAssetInfo.setDeptId(userInfoTool.getUserDeptId());
        return acAssetInfoMapper.selectAcAssetInfoIoc(acAssetInfo);
    }

    /**
     * 新增资产台账管理
     *
     * @param acAssetInfo 资产台账管理
     * @return 结果
     */
    @Override
    public int insertAcAssetInfo(AcAssetInfo acAssetInfo) {
        acAssetInfo.setDeptId(userInfoTool.getUserDeptId());
        acAssetInfo.setCreateBy(userInfoTool.getUserName());
        acAssetInfo.setCreateTime(userInfoTool.getCurrentDate());
        acAssetInfo.setAssetIsDelete(0);
        return acAssetInfoMapper.insertAcAssetInfo(acAssetInfo);
    }

    /**
     * 修改资产台账管理
     *
     * @param acAssetInfo 资产台账管理
     * @return 结果
     */
    @Override
    public int updateAcAssetInfo(AcAssetInfo acAssetInfo)
    {
        acAssetInfo.setUpdateBy(userInfoTool.getUserName());
        acAssetInfo.setUpdateTime(userInfoTool.getCurrentDate());
        return acAssetInfoMapper.updateAcAssetInfo(acAssetInfo);
    }

    /**
     * 批量删除资产台账管理
     *
     * @param assetIds 需要删除的资产台账管理主键
     * @return 结果
     */
    @Override
    public int deleteAcAssetInfoByAssetIds(Long[] assetIds)
    {
        return acAssetInfoMapper.deleteAcAssetInfoByAssetIds(assetIds);
    }

    /**
     * 删除资产台账管理信息
     *
     * @param assetId 资产台账管理主键
     * @return 结果
     */
    @Override
    public int deleteAcAssetInfoByAssetId(Long assetId)
    {
        return acAssetInfoMapper.deleteAcAssetInfoByAssetId(assetId);
    }

    // ******************************************************************************
    /**
     * 校验新增资产信息
     * @param acAssetInfo 资产信息
     * @return 结果
     * **/
    @Override
    public int checkAndInsertAssetInfo(AcAssetInfo acAssetInfo) {
        /*
         * 新增资产：
         * 1、判断资产名称是否存在
         * 2、若资产名称存在->对资产编号拆分->并对原有存在的资产编号更新->当前资产编号顺延
         * 3、若名称不存在->生成资产编号
         * 4、判断自定义编号是否存在
         * 5、自定义编号存在不能新增
         * */
        MatchInsertAssetInfoBO matchInsertAssetInfoBO = new MatchInsertAssetInfoBO();
        matchInsertAssetInfoBO.setAssetCustomNum(acAssetInfo.getAssetCustomNum());  // 首先匹配自定义编号，如果有重复返回 0
        System.out.println(userInfoTool.getUserDeptId());
        matchInsertAssetInfoBO.setDeptId(userInfoTool.getUserDeptId());  // 匹配公司/部门id
        int matchCustom = acAssetInfoMapper.matchInsertAssetInfo(matchInsertAssetInfoBO);  // 0：没匹配，大于0：有匹配
        if(0 != matchCustom) {  // 自定义编号重复
            return 0;
        }
        matchInsertAssetInfoBO.setAssetCustomNum(null);  // 重置自定义编号，防止查询出错
        matchInsertAssetInfoBO.setAssetName(acAssetInfo.getAssetName());  // 匹配资产名称，需要拆分资产编号
        int matchAssetName = acAssetInfoMapper.matchInsertAssetInfo(matchInsertAssetInfoBO);  // 0：没匹配，大于0：有匹配
          /*
            1、查询该名称所有资产信息
            2、判断（资产编号-附）是否为null
            3、如果为null时，证明第一次拆分
            4、旧数据（资产编号-附）为1
            5、新数据（资产编号-附）为2
         */
        if(0 != matchAssetName) {  // 资产名称重复
            if(1 == matchAssetName) {  // 1 == matchAssetName时：只有一条记录，未拆分
                /*
                    1、查询该名称所有资产信息（仅一条数据）
                    2、当前（资产编号-附）为null
                    3、旧数据（资产编号-附）为1
                    4、新数据（资产编号-附）为2
                    5、新数据（资产编号-主）为旧数据（资产编号-主）
                */
                AcAssetInfo oldAssetInfo = acAssetInfoMapper.selectAcAssetInfoByAssetNameOnly(matchInsertAssetInfoBO);
                oldAssetInfo.setAssetNumAttached(1L);  // 旧数据（资产编号-附）为1
                this.updateAcAssetInfo(oldAssetInfo);  // 更新旧数据

                acAssetInfo.setAssetNumAttached(2L);  // 新数据（资产编号-附）为2
                acAssetInfo.setAssetNumMaster(oldAssetInfo.getAssetNumMaster());  // 新数据（资产编号-主）为旧数据（资产编号-主）

            } else if(1 < matchAssetName) {  // 1 < matchAssetName时：有多条记录
                   /*
                    1、查出（资产编号-附）最大值记录
                    2、新数据（资产编号-附）为旧数据MAX（资产编号-附）+1
                    3、新数据（资产编号-主）为旧数据（资产编号-主）
                */
                AcAssetInfo oldAssetInfo = acAssetInfoMapper.selectAcAssetInfoByMaxNumAttachedOnly(matchInsertAssetInfoBO);  // 查出（资产编号-附）最大值记录
                acAssetInfo.setAssetNumAttached(oldAssetInfo.getAssetNumAttached() + 1);  // 新数据（资产编号-附）为旧数据MAX（资产编号-附）+1
                acAssetInfo.setAssetNumMaster(oldAssetInfo.getAssetNumMaster());  // 新数据（资产编号-主）为旧数据（资产编号-主）
            }

        } else {  // 资产名不重复
            /*
             * 1、生成一个资产编号（6位）
             * 2、附编号是为null->不用管
             * 3、数据库判断随机生成编号是否重复，如若重复重新生成
             * */
            Long newAssetNumMaset = 100000L;
            while(true) {  // 循环判断生成的6位随机数是否
                newAssetNumMaset = assetInfoTool.generateRandomNumber();  // 随机生成一个新的六位资产编号
                int matchNumMaster = acAssetInfoMapper.matchAssetInfoByNumMaster(newAssetNumMaset);// 新编号查询是否重复
                if(0 == matchNumMaster) {
                    break;
                } else {
                    continue;
                }
            }
            acAssetInfo.setAssetNumMaster(newAssetNumMaset);

        }
        LocalDateTime localDateTime = LocalDateTime.now();
        Timestamp nowData = Timestamp.valueOf(localDateTime);
        acAssetInfo.setAssetDate(nowData);
        return this.insertAcAssetInfo(acAssetInfo);
    }

    /**
     * 复制和更新资产信息
     * @param copyAcAssetInfoPOJO 新资产信息与复制对象的信息
     * @return 结果
     * **/
    @Override
    public int copyAndUpdateAssetInfo(AcAssetInfo copyAcAssetInfoPOJO) {
        copyAcAssetInfoPOJO.setAssetId(null);
        copyAcAssetInfoPOJO.setAssetNumMaster(null);
        copyAcAssetInfoPOJO.setAssetNumAttached(null);
        return this.checkAndInsertAssetInfo(copyAcAssetInfoPOJO);

    }
    /**
     * 查询资产详情
     * @param assetId 资产id
     * @return 资产详情
     * **/
    @Override
    public AcAssetInfoVO selectAssetInfoByAssetId(Long assetId) {
        return acAssetInfoMapper.selectAssetInfoByAssetId(assetId);
    }

    /**
     * 资产详情-资产在租详情
     * **/
    @Override
    public AcAssetLeaseInfoVO selectAssetLeaseInfoByAssetId(Long assetId) {
        SelectAcAssetLeaseInfoBO selectAcAssetLeaseInfoBO = new SelectAcAssetLeaseInfoBO();
        selectAcAssetLeaseInfoBO.setAssetId(assetId);
        selectAcAssetLeaseInfoBO.setDeptId(userInfoTool.getUserDeptId());
        System.out.println(selectAcAssetLeaseInfoBO.getDeptId());
        selectAcAssetLeaseInfoBO.setLeaseStatus("0");
        return acAssetInfoMapper.selectAssetLeaseInfoByAssetId(selectAcAssetLeaseInfoBO);
    }

    public List<AcWorkOrder> selectAssetFixByAssetId(Long assetId) {
        return acAssetInfoMapper.selectAssetFixByAssetId(assetId);
    }


    public List<AcWorkOrder> selectAssetCheckByAssetId(Long assetId) {
        return acAssetInfoMapper.selectAssetCheckByAssetId(assetId);
    }



    /**
     * 资产详情-资产租赁历史详情
     * **/
    @Override
    public List<AcAssetLeaseInfoVO> selectAssetHistoryLeaseInfoByAssetId(Long assetId) {
        SelectAcAssetLeaseInfoBO selectAcAssetLeaseInfoBO = new SelectAcAssetLeaseInfoBO();
        selectAcAssetLeaseInfoBO.setAssetId(assetId);
        selectAcAssetLeaseInfoBO.setDeptId(userInfoTool.getUserDeptId());
        selectAcAssetLeaseInfoBO.setLeaseStatus("1");
        return acAssetInfoMapper.selectAssetLeaseInfoByAssetIdList(selectAcAssetLeaseInfoBO);
    }

    /**
     * 根据资产状态，检查并删除资产
     * **/
    @Override
    public int checkAndDeleteAcAssetInfo(Long[] assetIds) {
        for(Long assetId : assetIds) {  // 去匹配每个id对应的资产租赁状态
            AcAssetInfo info = acAssetInfoMapper.selectAcAssetInfoByAssetId(assetId);
            if(info.getAssetStatus().equals("1")) {  // 状态1未在租，不可删除
                return 0;
            }
        }
        return this.deleteAcAssetInfoByAssetIds(assetIds);
    }

    /**
     * 资产状态定时器
     * 定时更新资产在租状态
     * **/
    @Override
    public void updateAcAssetInfoByAssetStatus() {
        List<SelectExpireAssetInfoBO> expireAssetInfo = acAssetInfoMapper.selectExpireAssetInfo();
        for(SelectExpireAssetInfoBO selectExpireAssetInfoBO : expireAssetInfo) {
            AcAssetInfo assetInfo = new AcAssetInfo();
            Long updateAssetId = selectExpireAssetInfoBO.getAssetId();  // 到期资产id
            assetInfo.setAssetId(updateAssetId);
            assetInfo.setAssetStatus("0");
            this.updateAcAssetInfo(assetInfo);  // 更新资产状态
        }
    }

    @Override
    public List<AcAssetInfo> selectAssetNum() {
            return  acAssetInfoMapper.selectAssetNum();
    }

    @Override
    public List<AcAssetInfo> selectAssetLocation() {
        return acAssetInfoMapper.selectAssetLocation();
    }

    @Override
    public List<AcAssetInfo> selectAssetStatus() {
        return  acAssetInfoMapper.selectAssetStatus();
    }

    @Override
    public List<AcAssetInfo> selectAssetType() {
        return  acAssetInfoMapper.selectAssetType();
    }

    @Override
    public List<AcAssetInfo> selectAssetProperty() {
        return  acAssetInfoMapper.selectAssetProperty();
    }

    @Override
    public List<AcAssetInfo> selectAssetBookValue() {
        return  acAssetInfoMapper.selectAssetBookValue();
    }

    @Override
    public List<AcAssetInfo> selectAssetRentNum() {
        return  acAssetInfoMapper.selectAssetRentNum();
    }

    @Override
    public List<AcAssetInfo> selectAssetChangeType() {
        return  acAssetInfoMapper.selectAssetChangeType();
    }

    @Override
    public List<AcAssetInfo> selectAssetTop5() {
        return  acAssetInfoMapper.selectAssetTop5();
    }


}
